/*
 * TIMER.c
 *
 *  Created on: May 4, 2010
 *      Author: iandrono
 */

#include <avr/io.h>
#include <avr/interrupt.h>
#include "timer.h"
#include "../leds/leds.h"
#include "../acelerometer/acelerometer.h"


typedef enum {PRESCALER_0, PRESCALER_8, PRESCALER_64, PRESCALER_256, PRESCALER_1024} PrescalerMode;

typedef struct {
	long freq;
	PrescalerMode prescaler;
	int comparator;
	int timer_counter;
} timerConfig;


//Timer Handler variables
volatile int counter;
volatile int timer_counter;

void initTimer( void ) {

	timerConfig config;
	config.freq = 8000000;
	config.prescaler = PRESCALER_256;
	config.comparator = 1;
	config.timer_counter = 10;

	//disable timer interrupt
	TIMSK0 = 0x00;

	//WGM01 = 1 => CTC
	TCCR0A = (1 << WGM01);

	//prescaler=x => interrumpe config->freq / x veces por segundo
	switch( config.prescaler ) {
		case PRESCALER_0:
			//CS02=0 CS01=0 CS00=1
			TCCR0B = (1<<CS00);
			break;
		case PRESCALER_8:
			//CS02=0 CS01=1 CS00=0
			TCCR0B = (1<<CS01);
			break;
		case PRESCALER_64:
			//CS02=0 CS01=1 CS00=1
			TCCR0B = (1<<CS01)|(1<<CS00);
			break;
		case PRESCALER_256:
			//CS02=1 CS01=0 CS00=0
			TCCR0B = (1<<CS02);
			break;
		case PRESCALER_1024:
			//CS02=1 CS01=0 CS00=1
			TCCR0B = (1<<CS02)|(1<<CS00);
			break;
	}

	//comparador=y => interrumpe config->freq / x / y veces por segundo
	OCR0A = config.comparator;
	timer_counter = config.timer_counter;

	//enable timer interrupt
	TIMSK0 = ( 1 << OCIE0A );
	counter = 0;
}

void setTimerCounter( unsigned char newTimerCounter ) {
	timer_counter = newTimerCounter;
	counter = 0;
}

unsigned char getTimerCounter() {
	return timer_counter;
}

SIGNAL(TIMER0_COMPA_vect) {
	counter++;
	if( counter >= timer_counter ) {
		updateLeds();


		#if WITH_ACEL
		//acelerometerAdjust();
		adjustCounters();
		#endif

		counter = 0;
	}
}
